
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>8. 错误和异常 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="9. 类" href="classes.html" />
    <link rel="prev" title="7. 输入输出" href="inputoutput.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/tutorial/errors.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="classes.html" title="9. 类"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="7. 输入输出"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 教程</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="errors-and-exceptions">
<span id="tut-errors"></span><h1><span class="section-number">8. </span>错误和异常<a class="headerlink" href="#errors-and-exceptions" title="永久链接至标题">¶</a></h1>
<p>到目前为止，我们还没有提到错误消息，但是如果你已经尝试过那些例子，你可能已经看过了一些错误消息。 目前（至少）有两种可区分的错误：<em>语法错误</em> 和 <em>异常</em>。</p>
<div class="section" id="syntax-errors">
<span id="tut-syntaxerrors"></span><h2><span class="section-number">8.1. </span>语法错误<a class="headerlink" href="#syntax-errors" title="永久链接至标题">¶</a></h2>
<p>语法错误又称解析错误，可能是你在学习Python 时最容易遇到的错误:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">while</span> <span class="kc">True</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hello world&#39;</span><span class="p">)</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>
    <span class="k">while</span> <span class="kc">True</span> <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Hello world&#39;</span><span class="p">)</span>
                   <span class="o">^</span>
<span class="gr">SyntaxError</span>: <span class="n">invalid syntax</span>
</pre></div>
</div>
<p>解析器会输出出现语法错误的那一行，并显示一个“箭头”，指向这行里面检测到第一个错误。 错误是由箭头指示的位置 <em>上面</em> 的 token 引起的（或者至少是在这里被检测出的）：在示例中，在 <a class="reference internal" href="../library/functions.html#print" title="print"><code class="xref py py-func docutils literal notranslate"><span class="pre">print()</span></code></a> 这个函数中检测到了错误，因为在它前面少了个冒号 (<code class="docutils literal notranslate"><span class="pre">':'</span></code>) 。文件名和行号也会被输出，以便输入来自脚本文件时你能知道去哪检查。</p>
</div>
<div class="section" id="exceptions">
<span id="tut-exceptions"></span><h2><span class="section-number">8.2. </span>异常<a class="headerlink" href="#exceptions" title="永久链接至标题">¶</a></h2>
<p>即使语句或表达式在语法上是正确的，但在尝试执行时，它仍可能会引发错误。 在执行时检测到的错误被称为 <em>异常</em>，异常不一定会导致严重后果：你将很快学会如何在 Python 程序中处理它们。 但是，大多数异常并不会被程序处理，此时会显示如下所示的错误信息:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="mi">10</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">ZeroDivisionError</span>: <span class="n">division by zero</span>
<span class="gp">&gt;&gt;&gt; </span><span class="mi">4</span> <span class="o">+</span> <span class="n">spam</span><span class="o">*</span><span class="mi">3</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">NameError</span>: <span class="n">name &#39;spam&#39; is not defined</span>
<span class="gp">&gt;&gt;&gt; </span><span class="s1">&#39;2&#39;</span> <span class="o">+</span> <span class="mi">2</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">TypeError</span>: <span class="n">Can&#39;t convert &#39;int&#39; object to str implicitly</span>
</pre></div>
</div>
<p>错误信息的最后一行告诉我们程序遇到了什么类型的错误。异常有不同的类型，而其类型名称将会作为错误信息的一部分中打印出来：上述示例中的异常类型依次是：<a class="reference internal" href="../library/exceptions.html#ZeroDivisionError" title="ZeroDivisionError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code></a>， <a class="reference internal" href="../library/exceptions.html#NameError" title="NameError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NameError</span></code></a> 和 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>。作为异常类型打印的字符串是发生的内置异常的名称。对于所有内置异常都是如此，但对于用户定义的异常则不一定如此（虽然这是一个有用的规范）。标准的异常类型是内置的标识符（而不是保留关键字）。</p>
<p>这一行的剩下的部分根据异常类型及其原因提供详细信息。</p>
<p>错误信息的前一部分以堆栈回溯的形式显示发生异常时的上下文。通常它包含列出源代码行的堆栈回溯；但是它不会显示从标准输入中读取的行。</p>
<p><a class="reference internal" href="../library/exceptions.html#bltin-exceptions"><span class="std std-ref">内置异常</span></a> 列出了内置异常和它们的含义。</p>
</div>
<div class="section" id="handling-exceptions">
<span id="tut-handling"></span><h2><span class="section-number">8.3. </span>处理异常<a class="headerlink" href="#handling-exceptions" title="永久链接至标题">¶</a></h2>
<p>可以编写处理所选异常的程序。请看下面的例子，它会要求用户一直输入，直到输入的是一个有效的整数，但允许用户中断程序（使用 <kbd class="kbd docutils literal notranslate">Control-C</kbd> 或操作系统支持的其他操作）；请注意用户引起的中断可以通过引发 <a class="reference internal" href="../library/exceptions.html#KeyboardInterrupt" title="KeyboardInterrupt"><code class="xref py py-exc docutils literal notranslate"><span class="pre">KeyboardInterrupt</span></code></a> 异常来指示。:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">x</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">&quot;Please enter a number: &quot;</span><span class="p">))</span>
<span class="gp">... </span>        <span class="k">break</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Oops!  That was no valid number.  Try again...&quot;</span><span class="p">)</span>
<span class="gp">...</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句的工作原理如下。</p>
<ul class="simple">
<li><p>首先，执行 <em>try 子句</em> （<a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 和 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 关键字之间的（多行）语句）。</p></li>
<li><p>如果没有异常发生，则跳过 <em>except 子句</em> 并完成 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句的执行。</p></li>
<li><p>如果在执行try 子句时发生了异常，则跳过该子句中剩下的部分。然后，如果异常的类型和 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 关键字后面的异常匹配，则执行 except 子句 ，然后继续执行 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句之后的代码。</p></li>
<li><p>如果发生的异常和 except 子句中指定的异常不匹配，则将其传递到外部的 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句中；如果没有找到处理程序，则它是一个 <em>未处理异常</em>，执行将停止并显示如上所示的消息。</p></li>
</ul>
<p>一个 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句可能有多个 except 子句，以指定不同异常的处理程序。 最多会执行一个处理程序。 处理程序只处理相应的 try 子句中发生的异常，而不处理同一 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句内其他处理程序中的异常。 一个 except 子句可以将多个异常命名为带括号的元组，例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="o">...</span> <span class="k">except</span> <span class="p">(</span><span class="ne">RuntimeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="ne">NameError</span><span class="p">):</span>
<span class="o">...</span>     <span class="k">pass</span>
</pre></div>
</div>
<p>如果发生的异常和 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句中的类是同一个类或者是它的基类，则异常和 except 子句中的类是兼容的（但反过来则不成立 --- 列出派生类的 except 子句与基类不兼容）。 例如，下面的代码将依次打印 B, C, D</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="n">B</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">C</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">for</span> <span class="bp">cls</span> <span class="ow">in</span> <span class="p">[</span><span class="n">B</span><span class="p">,</span> <span class="n">C</span><span class="p">,</span> <span class="n">D</span><span class="p">]:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">raise</span> <span class="bp">cls</span><span class="p">()</span>
    <span class="k">except</span> <span class="n">D</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;D&quot;</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">C</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;C&quot;</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">B</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;B&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>请注意如果 except 子句被颠倒（把 <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">B</span></code> 放到第一个），它将打印 B，B，B --- 即第一个匹配的 except 子句被触发。</p>
<p>最后的 except 子句可以省略异常名，以用作通配符。但请谨慎使用，因为以这种方式很容易掩盖真正的编程错误！它还可用于打印错误消息，然后重新引发异常（同样允许调用者处理异常）:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>

<span class="k">try</span><span class="p">:</span>
    <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;myfile.txt&#39;</span><span class="p">)</span>
    <span class="n">s</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
    <span class="n">i</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">OSError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;OS error: </span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">err</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Could not convert data to an integer.&quot;</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Unexpected error:&quot;</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">0</span><span class="p">])</span>
    <span class="k">raise</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> ... <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 语句有一个可选的 <em>else 子句</em>，在使用时必须放在所有的 except 子句后面。对于在try 子句不引发异常时必须执行的代码来说很有用。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;cannot open&#39;</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">&#39;has&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()),</span> <span class="s1">&#39;lines&#39;</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>使用 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句比向 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 子句添加额外的代码要好，因为它避免了意外捕获由 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> ... <code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code> 语句保护的代码未引发的异常。</p>
<p>发生异常时，它可能具有关联值，也称为异常 <em>参数</em> 。参数的存在和类型取决于异常类型。</p>
<p>except 子句可以在异常名称后面指定一个变量。这个变量和一个异常实例绑定，它的参数存储在 <code class="docutils literal notranslate"><span class="pre">instance.args</span></code> 中。为了方便起见，异常实例定义了 <a class="reference internal" href="../reference/datamodel.html#object.__str__" title="object.__str__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__str__()</span></code></a> ，因此可以直接打印参数而无需引用 <code class="docutils literal notranslate"><span class="pre">.args</span></code> 。也可以在抛出之前首先实例化异常，并根据需要向其添加任何属性。:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">&#39;spam&#39;</span><span class="p">,</span> <span class="s1">&#39;eggs&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">inst</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">inst</span><span class="p">))</span>    <span class="c1"># the exception instance</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">inst</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>     <span class="c1"># arguments stored in .args</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">inst</span><span class="p">)</span>          <span class="c1"># __str__ allows args to be printed directly,</span>
<span class="gp">... </span>                         <span class="c1"># but may be overridden in exception subclasses</span>
<span class="gp">... </span>    <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">inst</span><span class="o">.</span><span class="n">args</span>     <span class="c1"># unpack args</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;x =&#39;</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;y =&#39;</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">&lt;class &#39;Exception&#39;&gt;</span>
<span class="go">(&#39;spam&#39;, &#39;eggs&#39;)</span>
<span class="go">(&#39;spam&#39;, &#39;eggs&#39;)</span>
<span class="go">x = spam</span>
<span class="go">y = eggs</span>
</pre></div>
</div>
<p>如果异常有参数，则它们将作为未处理异常的消息的最后一部分（'详细信息'）打印。</p>
<p>异常处理程序不仅处理 try 子句中遇到的异常，还处理 try 子句中调用（即使是间接地）的函数内部发生的异常。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">this_fails</span><span class="p">():</span>
<span class="gp">... </span>    <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">this_fails</span><span class="p">()</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">ZeroDivisionError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Handling run-time error:&#39;</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">Handling run-time error: division by zero</span>
</pre></div>
</div>
</div>
<div class="section" id="raising-exceptions">
<span id="tut-raising"></span><h2><span class="section-number">8.4. </span>抛出异常<a class="headerlink" href="#raising-exceptions" title="永久链接至标题">¶</a></h2>
<p><a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 语句允许程序员强制发生指定的异常。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">&#39;HiThere&#39;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">NameError</span>: <span class="n">HiThere</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 唯一的参数就是要抛出的异常。这个参数必须是一个异常实例或者是一个异常类（派生自 <a class="reference internal" href="../library/exceptions.html#Exception" title="Exception"><code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></a> 的类）。如果传递的是一个异常类，它将通过调用没有参数的构造函数来隐式实例化:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">raise</span> <span class="ne">ValueError</span>  <span class="c1"># shorthand for &#39;raise ValueError()&#39;</span>
</pre></div>
</div>
<p>如果你需要确定是否引发了异常但不打算处理它，则可以使用更简单的 <a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 语句形式重新引发异常</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">&#39;HiThere&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;An exception flew by!&#39;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">raise</span>
<span class="gp">...</span>
<span class="go">An exception flew by!</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">2</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">NameError</span>: <span class="n">HiThere</span>
</pre></div>
</div>
</div>
<div class="section" id="user-defined-exceptions">
<span id="tut-userexceptions"></span><h2><span class="section-number">8.5. </span>用户自定义异常<a class="headerlink" href="#user-defined-exceptions" title="永久链接至标题">¶</a></h2>
<p>程序可以通过创建新的异常类来命名它们自己的异常（有关Python 类的更多信息，请参阅 <a class="reference internal" href="classes.html#tut-classes"><span class="std std-ref">类</span></a>）。异常通常应该直接或间接地从 <a class="reference internal" href="../library/exceptions.html#Exception" title="Exception"><code class="xref py py-exc docutils literal notranslate"><span class="pre">Exception</span></code></a> 类派生。</p>
<p>可以定义异常类，它可以执行任何其他类可以执行的任何操作，但通常保持简单，通常只提供许多属性，这些属性允许处理程序为异常提取有关错误的信息。在创建可能引发多个不同错误的模块时，通常的做法是为该模块定义的异常创建基类，并为不同错误条件创建特定异常类的子类:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Error</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Base class for exceptions in this module.&quot;&quot;&quot;</span>
    <span class="k">pass</span>

<span class="k">class</span> <span class="nc">InputError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Exception raised for errors in the input.</span>

<span class="sd">    Attributes:</span>
<span class="sd">        expression -- input expression in which the error occurred</span>
<span class="sd">        message -- explanation of the error</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>

<span class="k">class</span> <span class="nc">TransitionError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Raised when an operation attempts a state transition that&#39;s not</span>
<span class="sd">    allowed.</span>

<span class="sd">    Attributes:</span>
<span class="sd">        previous -- state at beginning of transition</span>
<span class="sd">        next -- attempted new state</span>
<span class="sd">        message -- explanation of why the specific transition is not allowed</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">previous</span><span class="p">,</span> <span class="nb">next</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">previous</span> <span class="o">=</span> <span class="n">previous</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">next</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
</pre></div>
</div>
<p>大多数异常都定义为名称以“Error”结尾，类似于标准异常的命名。</p>
<p>许多标准模块定义了它们自己的异常，以报告它们定义的函数中可能出现的错误。有关类的更多信息，请参见类 <a class="reference internal" href="classes.html#tut-classes"><span class="std std-ref">类</span></a>。</p>
</div>
<div class="section" id="defining-clean-up-actions">
<span id="tut-cleanup"></span><h2><span class="section-number">8.6. </span>定义清理操作<a class="headerlink" href="#defining-clean-up-actions" title="永久链接至标题">¶</a></h2>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句有另一个可选子句，用于定义必须在所有情况下执行的清理操作。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="ne">KeyboardInterrupt</span>
<span class="gp">... </span><span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Goodbye, world!&#39;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">Goodbye, world!</span>
<span class="nc">KeyboardInterrupt</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">2</span>, in <span class="n">&lt;module&gt;</span>
</pre></div>
</div>
<p>如果存在 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句，则 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句将作为 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句结束前的最后一项任务被执行。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句不论 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句是否产生了异常都会被执行。 以下几点讨论了当异常发生时一些更复杂的情况：</p>
<ul class="simple">
<li><p>如果在执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 子句期间发生了异常，该异常可由一个 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句进行处理。 如果异常没有被某个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code> 子句所处理，则该异常会在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句执行之后被重新引发。</p></li>
<li><p>异常也可能在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句执行期间发生。 同样地，该异常会在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句执行之后被重新引发。</p></li>
<li><p>如果在执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句时遇到一个 <a class="reference internal" href="../reference/simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a>, <a class="reference internal" href="../reference/simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 或 <a class="reference internal" href="../reference/simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 语句，则 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句将在执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code>, <code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句之前被执行。</p></li>
<li><p>如果 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句中包含一个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句，则返回值将来自 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句的某个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句的返回值，而非来自 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 子句的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句的返回值。</p></li>
</ul>
<p>例如</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">bool_return</span><span class="p">():</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">True</span>
<span class="gp">... </span>    <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="kc">False</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bool_return</span><span class="p">()</span>
<span class="go">False</span>
</pre></div>
</div>
<p>一个更为复杂的例子:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">divide</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">result</span> <span class="o">=</span> <span class="n">x</span> <span class="o">/</span> <span class="n">y</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;division by zero!&quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;result is&quot;</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;executing finally clause&quot;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">divide</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">result is 2.0</span>
<span class="go">executing finally clause</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">divide</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">division by zero!</span>
<span class="go">executing finally clause</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">divide</span><span class="p">(</span><span class="s2">&quot;2&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">)</span>
<span class="go">executing finally clause</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">3</span>, in <span class="n">divide</span>
<span class="gr">TypeError</span>: <span class="n">unsupported operand type(s) for /: &#39;str&#39; and &#39;str&#39;</span>
</pre></div>
</div>
<p>正如你所看到的，<a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句在任何情况下都会被执行。 两个字符串相除所引发的 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 不会由 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句处理，因此会在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句执行后被重新引发。</p>
<p>在实际应用程序中，<a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句对于释放外部资源（例如文件或者网络连接）非常有用，无论是否成功使用资源。</p>
</div>
<div class="section" id="predefined-clean-up-actions">
<span id="tut-cleanup-with"></span><h2><span class="section-number">8.7. </span>预定义的清理操作<a class="headerlink" href="#predefined-clean-up-actions" title="永久链接至标题">¶</a></h2>
<p>某些对象定义了在不再需要该对象时要执行的标准清理操作，无论使用该对象的操作是成功还是失败。请查看下面的示例，它尝试打开一个文件并把其内容打印到屏幕上。:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;myfile.txt&quot;</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>这个代码的问题在于，它在这部分代码执行完后，会使文件在一段不确定的时间内处于打开状态。这在简单脚本中不是问题，但对于较大的应用程序来说可能是个问题。 <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句允许像文件这样的对象能够以一种确保它们得到及时和正确的清理的方式使用。:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;myfile.txt&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>执行完语句后，即使在处理行时遇到问题，文件 <em>f</em> 也始终会被关闭。和文件一样，提供预定义清理操作的对象将在其文档中指出这一点。</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#">8. 错误和异常</a><ul>
<li><a class="reference internal" href="#syntax-errors">8.1. 语法错误</a></li>
<li><a class="reference internal" href="#exceptions">8.2. 异常</a></li>
<li><a class="reference internal" href="#handling-exceptions">8.3. 处理异常</a></li>
<li><a class="reference internal" href="#raising-exceptions">8.4. 抛出异常</a></li>
<li><a class="reference internal" href="#user-defined-exceptions">8.5. 用户自定义异常</a></li>
<li><a class="reference internal" href="#defining-clean-up-actions">8.6. 定义清理操作</a></li>
<li><a class="reference internal" href="#predefined-clean-up-actions">8.7. 预定义的清理操作</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="inputoutput.html"
                        title="上一章"><span class="section-number">7. </span>输入输出</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="classes.html"
                        title="下一章"><span class="section-number">9. </span>类</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/tutorial/errors.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="classes.html" title="9. 类"
             >下一页</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="7. 输入输出"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 教程</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>